{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2ee483b3",
   "metadata": {},
   "source": [
    "# 다양한 LLM 모델 활용"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3bf28f9e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# API KEY를 환경변수로 관리하기 위한 설정 파일\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "# API KEY 정보로드\n",
    "load_dotenv()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "edd6b300",
   "metadata": {},
   "outputs": [],
   "source": [
    "# LangSmith 추적을 설정합니다. https://smith.langchain.com\n",
    "# !pip install langchain-teddynote\n",
    "from langchain_teddynote import logging\n",
    "from langchain_teddynote.messages import stream_response\n",
    "\n",
    "# 프로젝트 이름을 입력합니다.\n",
    "logging.langsmith(\"CH04-Models\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2550920c-09d8-48b3-be2f-b36362c37989",
   "metadata": {},
   "source": [
    "## OpenAI\n",
    "\n",
    "### 개요\n",
    "OpenAI는 채팅 전용 Large Language Model (LLM)을 제공합니다. 이 모델을 생성할 때 다양한 옵션을 지정할 수 있으며, 이러한 옵션들은 모델의 동작 방식에 영향을 미칩니다.\n",
    "\n",
    "### 옵션 상세 설명\n",
    "\n",
    "`temperature`\n",
    "\n",
    "- 샘플링 온도를 설정하는 옵션입니다. 값은 0과 2 사이에서 선택할 수 있습니다. 높은 값(예: 0.8)은 출력을 더 무작위하게 만들고, 낮은 값(예: 0.2)은 출력을 더 집중되고 결정론적으로 만듭니다.\n",
    "\n",
    "`max_tokens`\n",
    "\n",
    "- 채팅 완성에서 생성할 토큰의 최대 개수를 지정합니다. 이 옵션은 모델이 한 번에 생성할 수 있는 텍스트의 길이를 제어합니다.\n",
    "\n",
    "`model_name`\n",
    "\n",
    "- 적용 가능한 모델을 선택하는 옵션입니다. 더 자세한 정보는 [OpenAI 모델 문서](https://platform.openai.com/docs/models)에서 확인할 수 있습니다.\n",
    "\n",
    "\n",
    "**모델 스펙**\n",
    "\n",
    "- 링크: https://platform.openai.com/docs/models\n",
    "\n",
    "| Model               | Input (1M) | Cached Input (1M) | Output (1M) | Context Window | Max Output Tokens | Knowledge Cutoff |\n",
    "|---------------------|------------|-------------------|-------------|----------------|-------------------|------------------|\n",
    "| gpt-4.1             | $2.00      | $0.50             | $8.00       | 1,047,576      | 32,768            | Jun 01, 2024     |\n",
    "| gpt-4.1-mini        | $0.40      | $0.10             | $1.60       | 1,047,576      | 32,768            | Jun 01, 2024     |\n",
    "| gpt-4.1-nano        | $0.10      | $0.025            | $0.40       | 1,047,576      | 32,768            | Jun 01, 2024     |\n",
    "| gpt-4o              | $2.50      | $1.25             | $10.00      | 128,000        | 16,384            | Oct 01, 2023     |\n",
    "| gpt-4o-mini         | $0.15      | $0.075            | $0.60       | 128,000        | 16,384            | Oct 01, 2023     |\n",
    "| o1                  | $15.00     | $7.50             | $60.00      | 128,000        | 65,536            | Oct 01, 2023     |\n",
    "| o1-mini             | $1.10      | $0.55             | $4.40       | 128,000        | 65,536            | Oct 01, 2023     |\n",
    "| o1-pro              | $150.00    | –                 | $600.00     | 128,000        | 65,536            | Oct 01, 2023     |\n",
    "| o3-mini             | $1.10      | $0.55             | $4.40       | 200,000        | 100,000           | Oct 01, 2023     |\n",
    "| gpt-4.5-preview     | $75.00     | $37.50            | $150.00     | –              | –                 | –                |\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5fc161c2",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "# ChatOpenAI 객체를 생성합니다.\n",
    "gpt = ChatOpenAI(\n",
    "    temperature=0,\n",
    "    model_name=\"gpt-4.1-mini\",  # 모델명\n",
    ")\n",
    "\n",
    "# 스트리밍 출력을 위하여 invoke() 대신 stream()을 사용합니다.\n",
    "answer = gpt.stream(\"사랑이 뭔가요?\")\n",
    "\n",
    "# 답변 출력\n",
    "stream_response(answer)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed2aa412",
   "metadata": {},
   "source": [
    "# Anthropic\n",
    "\n",
    "Anthropic은 인공지능(AI) 안전성과 연구에 중점을 둔 미국의 스타트업 기업입니다. 주요 정보는 다음과 같습니다:\n",
    "\n",
    "- **설립 연도**: 2021년\n",
    "- **위치**: 미국 샌프란시스코\n",
    "- **창립자**: OpenAI 출신 직원들 (Daniela Amodei와 Dario Amodei 등)\n",
    "- **기업 형태**: 공익기업(Public Benefit Corporation)으로 등록\n",
    "\n",
    "## Claude\n",
    "\n",
    "Claude는 Anthropic의 대표적인 대규모 언어 모델(LLM) 제품군입니다. \n",
    "\n",
    "- **API 키 발급**: [https://console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys)\n",
    "- **모델 리스트**: [https://docs.anthropic.com/en/docs/about-claude/models](https://docs.anthropic.com/en/docs/about-claude/models)\n",
    "\n",
    "\n",
    "![](images/anthropic-20241023.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "616c7a79",
   "metadata": {},
   "source": [
    "| model_name        | model                              | Anthropic API                                | AWS Bedrock                                   | GCP Vertex AI                      |\n",
    "|------------------|------------------------------------|--------------------------------------------|----------------------------------------------|-----------------------------------|\n",
    "| Claude 3.5 Opus  | 연말 출시 예정                         | 연말 출시 예정                                | 연말 출시 예정                                   | 연말 출시 예정                        |\n",
    "| Claude 3.5 Sonnet| claude-3-5-sonnet-20241022         | claude-3-5-sonnet-20241022                 | anthropic.claude-3-5-sonnet-20241022-v2:0     | claude-3-5-sonnet-v2@20241022      |\n",
    "| Claude 3.5 Haiku | 연말 출시 예정                         | 연말 출시 예정                                | 연말 출시 예정                                   | 연말 출시 예정                        |\n",
    "| Claude 3 Opus    | claude-3-opus-20240229             | claude-3-opus-20240229                     | anthropic.claude-3-opus-20240229-v1:0         | claude-3-opus@20240229             |\n",
    "| Claude 3 Sonnet  | claude-3-sonnet-20240229           | claude-3-sonnet-20240229                   | anthropic.claude-3-sonnet-20240229-v1:0       | claude-3-sonnet@20240229           |\n",
    "| Claude 3 Haiku   | claude-3-haiku-20240307            | claude-3-haiku-20240307                    | anthropic.claude-3-haiku-20240307-v1:0        | claude-3-haiku@20240307            |"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "95b38108",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_anthropic import ChatAnthropic\n",
    "\n",
    "# ChatAnthropic 객체를 생성합니다.\n",
    "anthropic = ChatAnthropic(model_name=\"claude-3-5-sonnet-20241022\")\n",
    "\n",
    "# 스트리밍 출력을 위하여 invoke() 대신 stream()을 사용합니다.\n",
    "answer = anthropic.stream(\"사랑이 뭔가요?\")\n",
    "\n",
    "# 답변 출력\n",
    "stream_response(answer)"
   ]
  },
  {
   "attachments": {
    "perplexity-pricing.png": {
     "image/png": "iVBORw0KGgoAAAANSUhEUgAAAooAAADkCAYAAAAfFQWPAAAKrmlDQ1BJQ0MgUHJvZmlsZQAASImVlwdUk8kWx+f70hsBAkgn9CZIJ4CU0AMovYpKSAKEEmIgiIgNWVyBFUVEmroCqxQF1wLIWrFgRVEB+4KIgPpcLIiKyvuAQ9jd186750zmd27u/OfeOTPn3A8AiipbKEyGpQFIEaSLgrxc6RGRUXTcCCABeYAHZGDN5qQJmQEBfgCxufmv9rEXQNPzXZNprX/9/7+aDJeXxgEACkA4lpvGSUH4ODI+cYSidABQhxC/9up04TTfRlhOhCSI8PNpjp/lT9McO8No8kxMSJAbwnQA8GQ2WxQPAHkh4qdncOIRHfJ0DWYCLl+AcDbCTikpqVyETyFsgMQIEZ7WZ8T+SSf+L5qxEk02O17Cs7XMGN6dnyZMZq/5P4/jf1tKsnhuD31kkBNE3kHTNSNn9jwp1VfCgtil/nPM587Ez3CC2Dt0jjlpblFznJYczJpjLtvdV6KTvNRvjuP4npIYfjorZI55aR7BcyxKDZLsGydyY84xWzSfgzgpVOJP4LEk+lkJIeFznMEPWyrJLSnYdz7GTeIXiYMktfAEXq7z+3pKziEl7U+181mStekJId6Sc2DP588TMOc10yIkuXF57h7zMaGSeGG6q2QvYXKAJJ6X7CXxp2UES9amI5dzfm2A5AwT2T4Bcwz8gBegA2/gDoKQOXCa0nmZ6dOFuKUK14j48QnpdCby2nh0loBjupBuYWZhBcD02529Gu+DZt4kpHBm3pdai1zpj8h72THviy0BoDUPAMWH8z6dvQBQcwFo6eCIRRmzPvT0DwYQARXJUAmoA21gAEyABbABDsAFeAAf4A9CQCRYATggAaQAEVgNssEmkAcKwHawC1SAfaAG1IHD4ChoBafAeXAZXAe3QQ94BPrBEHgFxsBHMAlBEA6iQDRICdKAdCFjyAJiQE6QB+QHBUGRUAwUDwkgMZQNbYYKoGKoAtoP1UO/Qieh89BVqBt6AA1Ao9A76AuMgsmwHKwG68GLYAbMhH3hEHg5HA+vgrPgXHgbXAZXw4fgFvg8fB3ugfvhV/A4CqBIKAWUJsoExUC5ofxRUag4lAi1HpWPKkVVo5pQ7ahO1F1UP+o16jMai6ah6WgTtAPaGx2K5qBXodejC9EV6Dp0C/oi+i56AD2G/o6hYFQxxhh7DAsTgYnHrMbkYUoxBzAnMJcwPZghzEcsFquA1cfaYr2xkdhE7FpsIXYPthl7DtuNHcSO43A4JZwxzhHnj2Pj0nF5uHLcIdxZ3B3cEO4TnoTXwFvgPfFReAE+B1+Kb8Cfwd/BD+MnCdIEXYI9wZ/AJawhFBFqCe2EW4QhwiRRhqhPdCSGEBOJm4hlxCbiJeJj4nsSiaRFsiMFkvikjaQy0hHSFdIA6TNZlmxEdiNHk8XkbeSD5HPkB+T3FApFj+JCiaKkU7ZR6ikXKE8pn6RoUqZSLCmu1AapSqkWqTtSb6gEqi6VSV1BzaKWUo9Rb1FfSxOk9aTdpNnS66UrpU9K90mPy9BkzGX8ZVJkCmUaZK7KjMjiZPVkPWS5srmyNbIXZAdpKJo2zY3GoW2m1dIu0YbksHL6ciy5RLkCucNyXXJj8rLyVvJh8pnylfKn5fsVUAp6CiyFZIUihaMKvQpfFqgtYC7gLdi6oGnBnQUTiiqKLoo8xXzFZsUexS9KdCUPpSSlHUqtSk+U0cpGyoHKq5X3Kl9Sfq0ip+KgwlHJVzmq8lAVVjVSDVJdq1qjekN1XE1dzUtNqFaudkHttbqCuot6onqJ+hn1UQ2ahpMGX6NE46zGS7o8nUlPppfRL9LHNFU1vTXFmvs1uzQntfS1QrVytJq1nmgTtRnacdol2h3aYzoaOkt0snUadR7qEnQZugm6u3U7dSf09PXC9bboteqN6Cvqs/Sz9Bv1HxtQDJwNVhlUG9wzxBoyDJMM9xjeNoKNrI0SjCqNbhnDxjbGfOM9xt0LMQvtFgoWVi/sMyGbME0yTBpNBkwVTP1Mc0xbTd8s0lkUtWjHos5F382szZLNas0emcua+5jnmLebv7MwsuBYVFrcs6RYelpusGyzfGtlbMWz2mt135pmvcR6i3WH9TcbWxuRTZPNqK2ObYxtlW0fQ44RwChkXLHD2LnabbA7ZffZ3sY+3f6o/R8OJg5JDg0OI4v1F/MW1y4edNRyZDvud+x3ojvFOP3s1O+s6cx2rnZ+5qLtwnU54DLMNGQmMg8x37iauYpcT7hOuNm7rXM7545y93LPd+/ykPUI9ajweOqp5Rnv2eg55mXttdbrnDfG29d7h3cfS43FYdWzxnxsfdb5XPQl+wb7Vvg+8zPyE/m1L4GX+CzZueTxUt2lgqWt/sCf5b/T/0mAfsCqgN8CsYEBgZWBL4LMg7KDOoNpwSuDG4I/hriGFIU8CjUIFYd2hFHDosPqwybC3cOLw/sjFkWsi7geqRzJj2yLwkWFRR2IGl/msWzXsqFo6+i86N7l+sszl19dobwiecXpldSV7JXHYjAx4TENMV/Z/uxq9ngsK7YqdozjxtnNecV14ZZwR3mOvGLecJxjXHHcSLxj/M740QTnhNKE13w3fgX/baJ34r7EiST/pINJU8nhyc0p+JSYlJMCWUGS4GKqempmarfQWJgn7F9lv2rXqjGRr+hAGpS2PK0tXQ5pkm6IDcQ/iAcynDIqMz6tDlt9LFMmU5B5Y43Rmq1rhrM8s35Zi17LWduRrZm9KXtgHXPd/vXQ+tj1HRu0N+RuGNrotbFuE3FT0qabOWY5xTkfNodvbs9Vy92YO/iD1w+NeVJ5ory+LQ5b9v2I/pH/Y9dWy63lW7/nc/OvFZgVlBZ8LeQUXvvJ/Keyn6a2xW3rKrIp2rsdu12wvXeH8466YpnirOLBnUt2tpTQS/JLPuxauetqqVXpvt3E3eLd/WV+ZW3lOuXby79WJFT0VLpWNlepVm2tmtjD3XNnr8vepn1q+wr2ffmZ//P9/V77W6r1qktrsDUZNS9qw2o7f2H8Un9A+UDBgW8HBQf764LqLtbb1tc3qDYUNcKN4sbRQ9GHbh92P9zWZNK0v1mhueAIOCI+8vLXmF97j/oe7TjGONZ0XPd41QnaifwWqGVNy1hrQmt/W2Rb90mfkx3tDu0nfjP97eApzVOVp+VPF50hnsk9M3U26+z4OeG51+fjzw92rOx4dCHiwr2LgRe7LvleunLZ8/KFTmbn2SuOV05dtb968hrjWut1m+stN6xvnLhpffNEl01Xyy3bW2237W63dy/uPnPH+c75u+53L99j3bves7Snuze0935fdF//fe79kQfJD94+zHg4+WjjY8zj/CfST0qfqj6t/t3w9+Z+m/7TA+4DN54FP3s0yBl89Tzt+deh3BeUF6XDGsP1IxYjp0Y9R2+/XPZy6JXw1eTrvH/I/KPqjcGb43+4/HFjLGJs6K3o7dS7wvdK7w9+sPrQMR4w/vRjysfJifxPSp/qPjM+d34J/zI8ufor7mvZN8Nv7d99vz+eSpmaErJF7JlWAIUMOC4OgHcHAaBEAkBD+nListneesag2e+BGQL/iWf77xmzAaCmD4CQtQD43QSgvAIAPUSfGg1AABXxOwDY0lIy5vrgmZ592tSRb4ZlpYCSOQz+jc3283/K++8zmFa1An+f/wnj5wrnaOxlKgAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAACiqADAAQAAAABAAAA5AAAAAAwDEMaAABAAElEQVR4Ae2dB5gUxdPGiyQ5g+QgOSkoSUAQRVAkqEhGEFExECWDgIggkiUICAgICn+iBEHJGSQnQbLknJOAAl+9w/Z+c3u7e3u3u8cd99bz7M5sT09Pz296pmuqqntjJUyX7oFQSIAESIAESIAESIAESMCFQGyX3/xJAiRAAiRAAiRAAiRAAhYBKopsCCRAAiRAAiRAAiRAAm4JUFF0i4WJJEACJEACJEACJEACVBTZBkiABEiABEiABEiABNwSoKLoFgsTSYAESIAESIAESIAEqCiyDZAACZAACZAACZAACbglQEXRLRYmkgAJkAAJkAAJkAAJUFFkGyABEiABEiABEiABEnBLgIqiWyxMJAESIAESIAESIAESoKLINkACJEACJEACJEACJOCWwGOjKKZ78kmJEzeu25MMVGLG9OkDVRTLIQESIAESIAESIIEoTyDaK4pQ3saNHCnLfv1VVsyfLw3r1g049NIlS8q86dNlybx5MnfqVClVvHjAj8ECSYAESIAESIAESCCqEYiVMF26B/5W6r2GDeWtKlW8FvPvf//JhYsX5fSZM7J05UpZt2GD3Lt3z+s+vmz8vF07aVCnjjPrnbt3pULVqnLp8mVnmr8rc6ZMkdy5cjmL2bNvn9R85x3nb66QAAmQAAmQAAmQwONIICC+2jSpUkmunDl95lO7Rg05c/asdO7RQzZs3uzzfu4y5s+bN0Ry/CeekBzZswdMUUyUKJFkyZIlxDGyZ80qCRMkkH9u3w6Rzh8kQAIkQAIkQAIk8DgReGSu5/Tp0skP330nb6n1zx/5edq0ELsfOHhQNm/bFiLNnx+3bt2SOerWtstsdUFTSbQT4ToJkAAJkAAJkMDjSCAgFsWIgokdO7Z079xZ9uzfL/v0ExH5bfFiOa3WyWqVK8uBQ4dk/sKFESnG6z69BwyQdRs3SrlSpWTF2rWycs0ar/m5kQRIgARIgARIgAQeBwIBiVFs36qVvOcSs7dl+3aZMXu2xSixum/zqYu4rCpaGJ3sKr8vWSJtVGGkkAAJkAAJkAAJkAAJRB0CQbMoHjl2TOboKGS7pEqZUsYOG2Ypjfb0CuXLS9KkSeX69evyUrlykiJZMvtmWbR8udy8edPKU0G3Q+lcvW6drP3jD7f5Yf07e+5ciDLMj5RahzI6ijm9KqxYP3f+vBw9flz+0gEq7vaJp1PuVH3tNbO7czn399/lng7QgQvddRT0XwcOyF4tD5JV4xtLFCsmWTNnlr///tuKyTylA3rCEtTt5RdftPa7cvWq7PnrL9mqyjcGBbk75jkdKLR2/fqwiuV2EiABEiABEiABEvCZQNAURXc1wEjkIaNGycjBg0NshjIGRWq3KkMtmjYNpUhu3blT6r79trT85BNBXggGk0BRbPnRR5I3T54Q5X3SunUopQ/KVcfPPpMKqnzFdTPfIpS+2QsWyKixY+Xk6dPO8hIkTCi9v/jC+dusLFy6VG7pPgXy5Qu1fdS4cZai2OzDD+WjJk1CHe+gusg/bNkyVB1RNtzxrZs1k0b16skT8eKZw1lLKLNtunSRnE89FeqY6zdtoqIYghZ/kAAJkAAJkAAJ+Esg0gez7Nq9222d3bmkTcZnChaUti1aOJVEk+7rsvhzz8msn36SVytUCKW0mTIwWffb1avLbJ0Kx1XxNHl8XUKZLaNu9maq9LpTSjFCfIxaVpO7WE5R/qCvv5YPGjUKpSRiG0Z4T9A5I5MkToyfFBIgARIgARIgARIIKoFIVxQzqGXPncC17EmauMQ/esrnLh0K6DAdjJIiRQp3m0OlJVYlbJRaPNOmSRNqm68JiMnsqvM7epNcOXJID7UO2uXtN9+USqrMehOcT4uPP/aWhdtIgARIgARIgARIICAEIl1RrFypktuKn7K5e10zGAvf/fv35eDhw3Lk6FH5z8fJurt37CjJNP7RLnAzL162TLqr9Q5u4lv//GPfbA24qf3WWyHSwvMD80Rm07kWEfO4fNUquXHjhtvdSxYt6kyHyxludHeyY9cu+W7MGFmxerXc/fdfyZQhg7tsTCMBEiABEiABEiCBgBKIlBjFWLFiWYrTmzpnYhP9FxdXQcze8ZMnXZND/J6sf6H37YgRTqULZYYlsAq++MILobKNVOVwhCpeRjbppN8/aNl2ebViRUs5s6f5ug6lb67GO2JC8QcPHljxlM1VCXQdGQ4rZ5ZMmaxzL/LMM26tmFNmzJCv+vZ1HrrSyy/Lt7bfzg1cIQESIAESIAESIIEAEwiaooh4v3KlS1vVTaQDQuDS9SQT9f+TvQkGrfTq1y9EFihgYckrOpoaSptdYOX7fvx4e5JgIAisdqjjIR2ZDKsllFfXfUPs5OUHLJ+or6kjJucerzGS79avH6pMDIaBklzCZl00RV+9dk0GDh1qflrLRWoJXaMjvl9wsA2xkT9IgARIgARIgARIIIAEgqYooo6+xPkt0tHDM375xesprdJJriMiWXQktavs139ugevZVerp6ORACabbueESc4n/ud6zd68UKlAgxGES6OhtSJrUqUOk4wcmEHd1iyN9x59/UlEECAoJkAAJkAAJkEBQCQRVUQyr5tNVQfxm0KCwssmxEyfCzOMuw5Np04ZKhhIXbHGn3OGYN/TvAD0J5ph0laMai+lOMEclhQRIgARIgARIgASCTSDSFUVMqr1UB3jMmjMnoP/J7A4UBn64irHguaY/6t937twJVYWkbqbPQSZMTk4hARIgARIgARIggWATCJqiuEcnh/68Z09n/e+qInT+woVQLllnhiCs4F9XXOWpbNlck6zfzxUpInfv3pXDR47ILS+WP7c7ByDx0qVLoUrJ4aGuObNnD5WXCSRAAiRAAiRAAiQQaAJBUxTxLyL79u8PdH3DVd5+/Ss9V8mv/+KC2EkorUYwaKX/V19JhvTprQEoZ86eFcQyNg9jLkSzfyCWR9y4xHPoP7BAgcVf9xlJkTy5VNSRzxQSIAESIAESIAESCDaB2ME+wKMsH3MYuloHE+lk2F/qRNfmrwBRP/zNHpRECKbdwXo8/fu8ez7O1Wjt6OfXspUrBaOl7QIFtp8qsPj/a9T7ucKFZWCfPuIu9tK+H9dJgARIgARIgARIIBAEgmZRDETl/C0D09L8b+bMUHM3li9bVtYuXizrNmyQTBkzSsH8+UMdCv/lHJlyUV3PS1asEMyTaJeMqrR+N3CgZen0Ze5I+75cJwESIAESIAESIAF/CDzWFkWAGar/jezOBZ4kSRLr7/LcKYmYt3HWvHn+cI3QvphY+/Lly273NUoiLKRDXCYHd7sDE0mABEiABEiABEjATwKPvaKIkc/vN28uG/TfV3yRXbt3y2edOrmda9GX/f3JA6tivffftyb7dlcOpt3p3ru37NP4SQoJkAAJkAAJkAAJBJvAY+16NvAuqZXuA1UW36xWTWq/+aY8XbCg2WQt8Q8q+CeWkT/8IHA5m39UCZEpkn4c00EtbzVoYP31IFzk+F9nTCmEf4z5Ra2cJ06dEqS7ygOX+EbX7fxNAiRAAiRAAiRAAuElECthunRh/xdeeEuN4vkxchgDVjDJNf7S77hO6H1Hp8aJLlJDFd5e3buHqO7s+fOlS48eIdL4gwRIgARIgARIgAT8IRAjLIqugK5cvSr4RDVBHGL2rFmlkFo8C+kAmwP6n9Pu/t6w3AsvhKo6LJEUEiABEiABEiABEggkgRipKAYSYKDKihM3rsz53//EPsn2f/qf1NmzZJHFy5fL5StXpMRzz1lT5WC6HLvgv6vnLVhgT+I6CZAACZAACZAACfhNIEa6nv2mFqQC3qxSRb6OgPv4p6lT5esBA4JUKxZLAiRAAiRAAiQQUwk89qOeo9OFnaNWwZlz54ZrMM1c3eebQYOi02myriRAAiRAAiRAAtGEAC2KUfBCPVOokHRu00YKP/2029pd01HQe/XvEcdNmiSr1q51m4eJJEACJEACJEACJOAvASqK/hIM4v74276sGqOYLXNm6/+pj+nobPwHNf6LmkICJEACJEACJEACwSZARTHYhFk+CZAACZAACZAACURTAoxRjKYXjtUmARIgARIgARIggWAToKIYbMIsnwRIgARIgARIgASiKQEqitH0wrHaJEACJEACJEACJBBsAlQUg02Y5ZMACZAACZAACZBANCVARTGaXjhWmwRIgARIgARIgASCTYCKYrAJs3wSIAESIAESIAESiKYEqChG0wvHapMACZAACZAACZBAsAlQUQw2YZZPAiRAAiRAAiRAAtGUABXFaHrhWG0SIAESIAESIAESCDYBKorBJszySYAESIAESIAESCCaEqCiGE0vHKtNAiRAAiRAAiRAAsEmQEUx2IRZPgmQAAmQAAmQAAlEUwJUFKPphWO1SYAESIAESIAESCDYBKgoBpswyycBEiABEiABEiCBaEqAimI0vXCsNgmQAAmQAAmQAAkEmwAVxWATZvkkQAIkQAIkQAIkEE0JUFGMpheO1SYBEiABEiABEiCBYBOgohhswiyfBEiABEiABEiABKIpASqK0fTCsdokQAIkQAIkQAIkEGwCVBSDTZjlkwAJkAAJkAAJkEA0JUBFMZpeOFabBEiABEiABEiABIJNgIpisAmzfBIgARIgARIgARKIpgSoKEbTC8dqkwAJkAAJkAAJkECwCVBRDDZhlk8CJEACJEACJEAC0ZQAFcVoeuFYbRIgARIgARIgARIINgEqisEmzPJJgARIgARIgARIIJoSoKIYTS8cq00CJEACJEACJEACwSZARTHYhFk+CZAACZAACZAACURTAlQUo+mFY7VJgARIgARIgARIINgEqCgGmzDLJwESIAESIAESIIFoSoCKYjS9cKw2CZAACZAACZAACQSbABXFYBNm+SRAAiRAAiRAAiQQTQlQUYymF47VJgESIAESIAESIIFgE6CiGGzCLJ8ESIAESIAESIAEoikBKorR9MKx2iRAAiRAAiRAAiQQbAJxg30Alv/oCaRPl07y5MwpV65dk51//umxQuVKl7a2bdq6Vf65fdtjPm8bCuTLJ2lSpZI/Nm2Su//+6y2rPJk2rbxcrpzs2bfPa728FsKN0YpAyWLFJP4TT4So8/GTJ+XIsWPy4MGDEOmP6w8wiB07tqzfuNF5ivhd/LnnpFSJEnLx4kXZuGWL7Dt40LndrCRMkEDK6n1aKH9+OXbihKxcu1bOX7hgNlvLlClSyEtly0r2rFnl2o0bslfvrzV//BEiD3+En4B5jtr3xHPyL+V74+ZNe/Jju24YHPz7bzl1+rSY+3nH7t1y9epVt+edLUsWwefc+fOy98ABt3nCm5g8eXIpXLCg4Nnx99Gj4d2d+cNJIFbCdOlixtM5nGAep+yNGzSQEQMHWspfriJF5PKVK6FO75Xy5WXu//5npT+jHdHBw4dD5fElYdqECVL1tdckR+HCcubsWa+7vFimjPw2c6YMGDZMuvfu7TUvNz4eBA5u2yYZM2QIdTIntdNp3q6dLFy6NNQ2JNw4dcpSrqrWri3LVq1ymyc6JCZJnFiO7dkjt27dksyq7EHy5solk0aPlkIFCjhP4d69e9Khe3cZ+cMPzrQqr74qo4cMESiCRi6oUtnggw9k9fr1VlKxZ5+VqePHS4b06U0Wazl11ixp2qqV/BvGy1uInaL4j7hx4wqebdNnz/aopATyFMxz1F2ZM+bMkQ9btJA7d++G2ty5TRvp1qGD9WJQoXr1UNujU0L3jh2l02efSZsuXWTUuHFi7mdvz/CVCxZYL0Fog+99+qnb082fN6/kVmPGXM3ri5i+Y+Dw4dKtVy9fdmEePwjQ9ewHvOi2K6wRTd55x221WzRt6jY9oomxYsWK6K7c7zEncFOVpNdq1LA+1evVk7E//iiZVHmcMGKEJIgf3+3Zr1q3zlKG3L3kuN0hiiW+VbWqpSysWbQoxDk+ES+eLJgxQ7Kp9e/thg3lSe0s36hfX26oJXCAdoA5sme3zgSW+unK6fSZM/L8K69I+jx5pF3XrpImdWoZPXSopUTjnvteFUkoiZ2//FIyaudb4uWXZfuuXVJHedfVz+Mkg7/+Wob27SspkiWL1NP6XhVx035bqAK4/9AhqfnGG9Lsww/d1uPo8eNW293hxZvjdscokphaPUSf60vcqG+/lfYtW7qt1YeNGgn6F1eBlRwfb4J7f9Py5ZaBwVs++zb2L3YawV+n6zn4jKPUEfAwGzJqlPz333/OesGiUVE7FHfy7DPPSFG1UiRVS8ife/fK0hUr5P79+86s6MBKlyxpPSTsrjS7GxF54FJLlDCh/KnWlOWrVzv350rMIwBrGRQ/I0u0k8ilClL5F16Q3NoWixQqJFkyZ5bFmg7LwW5td1OmT5es6r7ape0Hgo6iwosvSkG1ysH6vXjZslChDnC/Pq3uKSimaJt7tBx30rBOHet4P06ebJWZSjtGuBNxfHtbh9sNoRIZdHlAj7lIrZ+379yxikRHCvf5dVXw4BaePX9+iOPVUEvS226sSe/UrWspdl169pTfFi+2ysK5dO/TR4Z88418+O67ltLXQa2BEFgFTfjIiLFjrfsK5b5aoYL8888/kl8VyN+XLJEhI0da+a+oO7CJWnG26j338fvvy6SpU610+5enuns7X+yP7bgG6Z980nKT49nQpnlz+eXXX+WePl9qvvmmda+v27DBOhwsoZ+q9fPPv/6SOcoHgheDSlr3XE89JWfOnbOsxXZPBK7vs08/LWnSpJGt27fLhs2bLZc6ysYzBdLio48sL0mfQYOsdgHFpLC2oX+1Dtt37rQUZft1tHby4+vwkSPO9ot2DNf+YrUowg2L8B2EBqzSkIBntA5o67iuT2XLFiLUIKu2b+RLoS5UbEeZdvH1mQmX7jvafleuWSMJEyWSQvqsvXjpkqzQ3whNMOKNs7s6w1poJK2+jKCNeBO4ghtqWx6tHiW7NA/DAPGBtu8C+kKD0Avc9zjOWg2TQP2R9rK2L9xPuIdx/bfoB2LvX8zx8IIEQwiYfzN4sJXsiaPhhuuUNGlSy6p/Wj1gv+m9Y1zoceLEsZTcYLYlU/eovqSiGNWvUADqZ3/7wsMdb7//U5evkZYff2xWraXJD3c13C12QSf1eq1acunyZcF+fb74wno4mzxwhUHMjdyrWzdp06yZ2Wwtl2iHUlOtJ5SYScC0L3P2+J0rRw7r502N9YLyVLZUKenStq3VWfwwcaLkVQXoheefl4EappBIO8T506ZJUQ2jMIKO5AN1/UEBgWXjF1X6TMwt8qA99urfX6BMuIo53sdNmlgWOrMd7txq6upGrG2NatVkjB7bbjU5pHFa1bSThoKIDg5u3XhqIYQcUCuTXTFtqB0mPpAjauGD2xTyfPHi1vI3tTTa5Xcojaoo5lHFGYJ8iEXcumOHPZulFEJRRL5bqihCFjgUTpMRcWGoY97cuU1SiKW7uufTvN7OF9dihl6XZDZr3m5VAKHY7dfYSijQKPeOLo2iaCxTePbgOuEYs6dMEShNRq5dvy7v6nMFIQiwqEKxtAvi4r5ULijbiMkz+LvvLIUNL7d2wfOmurapQIlr+zVWX8QpQvlD3aDYoy3A2oiXDqTBTYqwiUZal6HaFmFNhvT/6ivL4oiwCrQhb89M17hvKDwoGy8UiPk2Ahd4I1Wg5/32W5ic3dXZriii/SRyhDJAsYMV14idRatPPpExavU2z35YCu0vR/a8Zn9YIvEyB0HoBT591XK5VRX8Bfpy+JyGMNllsqbhPncVXPNZP/0k6fSl5UdtUxBvHA03tB17KAc8Fq/o/YR7e7m20WC3JdfziKq/6XqOqlcmgPUyN+7narWAxeMzW5wIbpL6+oBCsDtifYy8pu4tKIkIli+rMYd5ixYVWDDwlowHE+LMen7+ueUKe1NdZYi3atWpU4iOFtYXKIkIzH9ZO9pC2rnA2oB4SE9uGnN8Lh9fArAsL/zlF+uzRC0xp7UjzZwxozUACm4606HA+pVFOw6490waqHRq3dpSEmG9KKjW7AJqWUJnDAscLBsddDuUxIkac4ttr+iLEZQ2xInZlUtXwrB0F1ELJty1C1Rxg7LaUF3jUHDw0gQltpZ2lNn0HuihFr+cagUbrEtTNygGuAdSaOdtv5dcj2P/jQEnkDMa6G+Xs2pdg6CzhVKZJVMmtzG/9nzICzFp1g/HF9LA3a7YYZO7ukOZ8Xa+2G+IKgso6xONV8O9j2cA3OCuYspHun0dv79TplAS2+pzJKsqC/W10wZDhCBAIYfyg8EKRfU5kl6VSigQeO7gOFBcDGO0AfyGwoGO/dfff5endIlnFqyzeN54u+6oS3ikaePGzva7UcsfqdYrPGMRg2fOEe5+tCV8TBqOkVYto4O1nV5Qpb+GWr/SqYIPhmhrrVRBjugzM6Fe27r6opNJLYpQtOOoNQ6uebQdb5xhaTT1s9fZVx44b1gw8RIGqyn6DSOfqvcKVkHcvxDTD5ntWJZUazIYQaAE4jriRQD3OJREKKz59SUJfRDuz/pqpHijShUrP75QJmLil86bJ6lSprTuP/D0lWN8PX/E+CKU46t+/Syl8UO9vs/qsSOjLTlPJIqvUFGM4hcokNWDxWHCzz9bD9Qy+nCFfPTee9Yo1O/GjAlxKLjtIOMmTbLM/XhgG2tMed2GoHm8EcNtskgflrAwjtGO27if8fDBAxoCKwBcVPVq1nSa9XEjUmImAbh00DHig7AFjMyF0gerD9xGpuMarBYYdEKuYtom2iNGPMJa1loVNFgzntSOuOJLL1m7XNY22UBfgpD/rEMRc9fuzPGGakgGLEAIjzCDSHCfwJUJpQj3QBF1g0JRgEKD8A10JmZ/WNNxD7hafVzr7+43Ona73NcOEJ2gKRvbwM1VjEsV+Uw4SVj57GWY8u11D+t84S7F4AOwgvUG9z6eARPUigsxZdqP47oOpRWuY+yLDh7PoYKq5OBZAWUfCuQ6DReAhegjVYDwLEEbQWzgXLWSuRNcN7wIo/6wFOXTOjZv397aB20kUAILomm/OdUSDitvFVVgwMCcO15SwMdVSqjyCiUYz02ECKC+YIiX+EuwZoXzmWmOB6stBoLAIgYFerNj0BisyN44w7JmyvBUZ9dzcPcb9wusmAgDgOD6fqDWQlgj4d4Nr5h7HC8HeHmEyxmxzBCzDetvqtKIAZToi/D8wP0HCYujOWeEvcB4cU1nBJmiscIQvLRGVluyDhgNvh76P6JBRVnFwBBAZwhrHmJHNqil7xONW8KIU7go4F4zYkamblMXgBF02sibUd3Xxs2x0xEzZs+DddyImdUKAnlTA/nxsYvrqEz7Nq4/vgTQLuCiw6CNsMQeY2XPi7aJqTbsljN01sYtiwc9BK4wV0F8oauYTmOnTvFhxKyjnZp2DKUQH7vgPjCKWUSm6YACAzcuzglKkxFYB1EvMIACCCXV3JMmD5bGioh8VxyzGWTUOrsKzgFKiYm/ct1ur3tY52vu3V02XijPKPWGJ9LcWZGQDgspBEoiPBSugmO01hG2bXXwBDwbUM7BAUri+y6hLGZfhB800GcbPCYYdIEPFICh33/vjCk0eSOyNOeFgUImBtRTOd7aLvbBdDJ2GaxWVMhErSvE12emqZOJ3bV21i9cG4QrPONw63rjbPbxVGez3dsSCiosqnCrI+YdsYVJkySRIXpesRw7mrp6K8dsc3ePm8FAuIdNu0LICl5yYGWu8/bblgcMZZg27ImjqQtijY2YKeFgBQ12WzLHjC7LkK+x0aXWrGe4CJibAksoenDNVKtc2XqgwhUC5dFYJkzBJ3U6EoiJv8E6HjbomE7pyMsT2nFBSthGtOEGe0GtRBDcyLAOQBArA5cCPjk1rqz3gAEywsWCaWXkFwn4QOCEtk0oaLA2GcHUMXBnw3KN9gmB+9G0O4Q+oN3NX7jQ7OJcmk7H3pZN7CAGVph2DIuGKS+x3geY0gmDUGAFjahgQAzkY7Wo2aWp4zfi6yDIB0te7bfesn7jC/fb+2q1gSxduVKW6AfKFAL6YfE0goEuUMxMWSbd0zKs8z3uGCSBwRt2Ke0YXAKedx3TxJhYTOTDyG4j5hphrkjDFEtMn4LrhI4aA1ZgIUqnLxWVdP0nDUXAy2xdVQjcCaxIJdVihzLgSoRrd5fGTXZVqyLCBKKCmOcm5gA0gufyZA3rGa9KlWHv6zPTtF14eOxi2i8GgkE8cXZVMO1l+LKOupv+5VuNEYV8pgOaYIiA8miPhfelPJMH/ZTrPY5BJRBsM8dEHHE+bYeIaW2s4Q/vqAcBEl6O1k62r+jQlmzVDfoqFcWgI370BzAPE1MTuJnRyXypc2HhgWyCf42yiPwYdQZBQDkeQnAFYXABBJ0S4g7xJod4EVglEWtlTVWhnRnEXgYGCcAdhEm/MQ8cLAiIqaGQQEQIYIQn5HNtj2h31iAXVdrgDkQQ+gqNZYJ0UwUBrjWMpp6go4Db6wADdF6uYu6Pr3VgFtx06CS+UGsWBLG7ZgJ6vFwhBgsDwr7p0cOK0fU0QMT1GJ5+Y3Q0rIVNdHDXtxqb9XqlStJXLVawimFgx886aAcyTOdZhCAeDnG/iMvCYBK4MhFHjBhMTJ2D+fww0nO2uoFRX1hVMUejta8qI75IWOcLizDiGGG5xfMBjDGw7bWKFa3iwdOM4oVrEPVBvFlXm+UQ1k1YgGF9grILixBGn/+g4QZQhvFswXNiuMa+ofy16lrd7BjxitHvEJwvBM8WxKSiPtjnK502CPNVYtT6MXVbQowF0/rxCL/gEoblCi82aEt4Uf9a58uE5QsvHOa56+sz07Rd3APtdJAHntN4riNeE8oS2oU3zmhj/og5Psqw3Mw6ChxWRcQrIr4Q7miEUUDsea0Exxfic3HuUAxxHTHIydzDmIMS54QYUwykgaDtGUUR/RBCqhrr/YLzxSAhjPwPL0dHVZwL1CWqtyVnZSNhha7nSIAc1Q6BtzC4JvAwmajxMXDPuAriZxDPCLfPKltMEEY9Y+oBuMmq6QNhkrpKBmonjQ/ExBxh3V4GJl01goclApcx9QklZhFAZ2FeSDydubsOxZ7WV182MFITHYfpPLAdQfBw5WJ7OW1bUL7wMTJILR52F6tJN0u4sZbOnWt+WiNRcX9gJGqbzp1lqAa7Y2SlEShMX3z9tccO0OTztoQFsK5aD+eptQzuVXwg6PwQZI9jQDCKGkH6IzQuE6M5jUAx/lgD/41gbkWMgEYclz2Wq6cOPoHS6yp2rmYbRld7O1/kw4AJKHWIBTSjjnHvm3kwUV88JzA582aHVRTKnl1aqCL/iz5jhilXfIy01/PDdcLgOZS9XRVhIzhfMwULrFXv6mAjvARAntNzxoAMKJz4GIEV2T4dk0kP79Kw8tZ+TR572fY0w3aIS1vCeeEawf1rnrvunpn2cu3rULwxuBAfCEadt9Y2i/bljTPatr1+9jIjsj5cX0qg7KFc+8hpb2Wh/8G1RDwxXtKw/pkqu7iH7fcEysAAN3jEXPsOhFTUU4PFMh3UMlWt0EXVs+CNo+v+9vqBxwyN84RVNFhtyX686LDOf2aJDlfJzzrCAgJrnvnbJRSHNz68ZWNOMxMbhTc5vEkZiwLyISbLzKMIN84ytSbaH5RwLWGEGTonvN1d1zdUvCXb/8IPZRTTt34EHKNszG2GgH+MuMabIjr3iP4TDOpIiT4E4K5ETJ+ZMsVdzTGyHpMoQ7Exbc01DRaFCtqpYI41zBW4XK0MCHo3Aou5mYMNI0y3qQIB64q7TnGRdgqwyGBUPpZmHkUMTrDnh2ULVkvcI1BI0JbRQUPQOcI6g/SwBG5B1N8M/EJ+WMPQMSK0A+7u9foXmO7uCXDAPZNK7x2cL6wr5v41x4U1DQN6cI9joBBeCjH/oCfxVHdv52vKgqUQ9caUOHDvwhraWK2Y0zQMAGINBlKrJ54H29SCiOtv/ys3DBKqqNcRlmG4R5EHrkUjmG4HLsd0yhxuVHgz7K5+tCV4PPC3kLge/6llCnXCS7BJw3MpEGKeo1Dq7HW0lw1m+MCla6zX7v5uDnkQpoPzQpw32q/9vDw9M+3HwjoUHvy7FabegaX9aZ0lALGisKjZYw69cXZXZ9fjmN+IHc2tL1SmL8H1xL1m2jLWcQ/hvjDx7Ri8A6uv/bqb8uxLtH20IZPPfg/D87VFDQwmDtkdU5SF6XVwb+D+gbLqiaO7/dE/4d68oPzwrED4RrDakv28o8M6FcXocJVYRxIggaARwGTJUGhSqWJlJtAO2sEe44JhgenXs6cVI4iBDZTgE0BYBf7Zh39lF3zWMfkIsWPyyfPcSYAESMBuNSQN/wmQp/8MfS2BrH0lxXz+EKBF0R963JcESIAESIAESIAEHmMCtCg+xheXp0YCJEACJEACJEAC/hCgougPPe5LAiRAAiRAAiRAAo8xASqKj/HF5amRAAmQAAmQAAmQgD8EqCj6Q4/7kgAJkAAJkAAJkMBjTICK4mN8cXlqJEACJEACJEACJOAPASqK/tDjviRAAiRAAiRAAiTwGBOgovgYX1yeGgmQAAmQAAmQAAn4Q4CKoj/0uC8JkAAJkAAJkAAJPMYEqCg+xheXp0YCJEACJEACJEAC/hCI68/O2DeT/qk5hQRIgARIgARIgARiAoGT58/HhNN0niP/ws+JgiskQAIkQAIkQAIkQAJ2AnQ922lwnQRIgARIgARIgARIwEmAiqITBVdIgARIgARIgARIgATsBKgo2mlwnQRIgARIgARIgARIwEmAiqITBVdIgARIgARIgARIgATsBKgo2mlwnQRIgARIgARIgARIwEmAiqITBVdIgARIgARIgARIgATsBKgo2mlwnQRIgARIgARIgARIwEmAiqITBVdIgARIgARIgARIgATsBPz+ZxZ7YWlTpZKkCRNK/HjxJJZ9A9dJgASiDYEHWtM7//4r1//5R85fuhRt6s2KkgAJkAAJBJ5AQP6Z5QlVDDM/+aT8e++eXLl5U25rJ3M/8HVliSRAApFAAG6GBHpPp0icWOLFiSMnzp2Tu3pPB1oyZ8woTzzxhBw+ciTQRbM8Egg6gVLFismWHTuCcm8EvfI8AAmEg0BAXM9QEq/fvi2nrlyRW1QSw4GfWUkg6hHASx7uY9zPuK9xfwdDihYpIi88/3wwimaZJBBUAnH1BaphnTqSNEkSr8dJpB622JrXV0mg+RPEj+9rduYjgUgh4LdFEe7mBGoVQKdCIQESePwIZEyRQm7fvRsQN3Qc7TTLlSolUBIzpU8vsWLHlqPHj8vaDRtk07Zt8uABHN8ifb/4wm0nDAvODz/99PhB5hlFCwJZMmWy2m+Rp5921vePzZtl5bp1cuHiRWdagXz5pHb16lYbjq1t/K/9+2Xi9OlyW8M53EnRwoXljcqVJWnSpIL8FzTkY9bcubJ73z532ZlGApFKwO8YRcQknr92LVIrzYORQCAIJFNrwC21mP3333+hiouvb/V4s78aDdp2+nTp5Kuu3aXft4PkwKFDoc7F3wSEk6RNlkzO+1uQ7l+1UiUpX6aMjBw/Xg6pyzmOdop5c+eWRrVrSzLtJJesXGkdJaE+V0ZNmCC79+4NcVSjSIZI5A8SiAQCUOJaf/SRbPvzT+k9aJBcuXpV0qVNKxVffFHafPKJ9Bw40FIE8+TMKR83biw/TZtmvfwkTJBA3m/QwNq375AhzpchU+W8mr+Jbv955kzZvHWr4GWq/AsvSFMto48e58z5QNx55mhckkD4CfjtesbAFcQkupPr2hGYz4xJk0Jk2bxqlXMb8kQFMXW1L32t19dqATH7+bpPTM/37DPPOJmBXcN69UIgMTyxdG0/ITK6+QElcOmv863yt61ZGyLHU9myyWUt86Q+8C8fPCjTJk6U2LEeDr9CvO3K3xfKBX2TP7Fzp5w5eEigiEHKlylrlQerQmRIWHxMHZ4uWFDqVqsiJYoWNUkBXeL+xn0eCHlG67pGrYf7VaG9pzHNiH3ctWeP/LZ0qZQpWdI6BK4BXHs3VEFFHvvn/n1GPwfiOrCM8BPIlT27FVM7a948S0lECWdViZs8a5bE0zZbKG9eq9DXKlSQPzZtko2q9OHF5pZaEcf+/LNk0OdIQbU0usrzxYvL30ePyjq9L3A//KMvr4uWL7eUzkIFCrhm528SiHQCfiuK6F49PbrLVKkm5d96y+1J1W7UyNq2fONGt9sfRWLh8uWl5KuvSoW337YOv07dXL7IXH1zbPHee7Juu2/5fSkzJuTZo8oY2oenNuKt/YTFB0pgwfwF5OLN0K6eBTNnCRycL77xhrTu9oVULldOaug6pFH9+vJcvrxSvWEjKVaxoiSOG0f69uxpbYvsr7D4mPosXrZMkmon9rO2w2AI7u+HarT/pd+8dUuyZskSqiB0qjPU1QZJlCiRtfxHO9hYqsBn0BjJ+BreQiGBR0kACh+sfVl0EJZd8PIySi3kR0+csLwQ+dRCvknbs13QlmEdt7uszfbla9bIhP/9z/y0lng5+k/LhdJIIYFHTcBvRdHbCezcvUu2aNzRdTcWR4x0xLaTp0+7LSIPbjZ1Q8GadHzvPqlbs6aVL4laipCGzh5LuNywrFezlrOcL7p0sdKQPmvyFME+vgjqdObsWS17pizTt7vKb77py26yfcdOeUpHwC1dsdyn/PZMzdWVgXric/rAQalcsZJzc251SRz7a69zu30b8vfv9bVz2wfvvuvc74m4ca3zNuXC2mnkdXX9If3zdu2t5f5t26W0w5Jj8nhallOX4UFVnk25KAPyZtVqcnDXLit9w4qVMn/GTGsd9Yd4qs+dO3esNoB24E68tR93+e1pE6bPkMx5c8uJk8ftydb6gkWL5G19UdmKeLdJP1pphQs9Yy3jOixnK9esln0HDsiFGzclblz31jTDskTR4qGO4Zrg7VqinU8cM0aO7P7L4jZS3VOQsPggj7kWWL5VrTqSnII0T20E9TmhirrZ3962nAUEYeV3VWqfyppVOrVqZcV6pU6Z0joKrIfGzQxXHQTWx349ekjH1q1loCrrVbTtUkjgURE4cPiw7FNL+EdqFKivxoS8uXJZlm/UB2EU5y9ckJQazws5Z4tXtBKQpttTObabNCyPqYJpj29EWnZ9mUqh4R5//vUXflJI4JESCKqi6M+ZTflhvKRInkLe0DiNrTu2y5gBA6y3OVPh0foGd/O/e2qdyCRzly6TDtqZQOB+a9e0qXTq3Ucat2wpFUuXkmYffuhzVdprOfE19+G//5bMProYu/fuJRf0IRBeQRxcn86dZdIvv1hWzGXqjv+qW1dnMRvVHZckYQL5VPPsPnxEpo0ZLQkcnSgyNahTS5p89pns2H9QBn/5pdN92rlDB+u862vczJeDB1vWzoIOF4ax1pR6vqTUUU5PpkwhY4Z/5zymt5XvhwyVm//cloq1astX334rnZo3kzRp0kjiRAklncbvFFLLXIHs2WTUD2MFUX8N6ta1ivNWH2/H82dbi/bt3MYeosy2XTrLcmUNgdsWslRdPZApDqvc1jXrBJbiNEkSS99Bg61t9i9cu6mjRwuszhu3bLJvcrvu7VpmUgvFW2q97N2/r4z6abK8o9bNwrZgebcFOhI79Ootnfv0sX4lTvzQEmfP76mNoD7Xr9+wruX85StDtS17GYFc36NWlW5a373q8q+uwftf6UtdS22HhfLnt6yHOJZpo1kzZ5Z+Q4dKm65dZZIOBKiijBD0TyGBR0EAlsOh338vE6ZMscJR0G77dOsm1dQLlVyVOghCXiA39cXHVW5pWlijpLFP8uTJ5YOGDa34xugQI+16nvz9+BEweleUO7NylV+V/MWKyho1y7fXjgJSqkQJZz137dktBw//Les1FmT/oYOSQUdQQrZrx51W40BGjRsr8xYskI1/7pbGDd5x7tfj888tKx0sdfiULV3auQ0r01VpG6jWnQ9UyUGsWiBk4Zw5IY4ZVy1+ELjVIPdU4T2iMSoN3m8ixVTZgqCzRK7PtL6T9MFUp3EjK720bTqRQcOHW/Vt2qqFta1EsYeWrW80qDq1WmR/W7xYhn73UAl0jf/7VBViWNZ6qgKeNW0ay+qHQrzxgXL04N59uXTlsg6c+NZyd9oV5KPHjln1gKXu8LETktFxTXypj7VjOL9ee6ViCK7mZcHXYqB0r5s/X45qnNGKtaut3fBgbq7Mc2bKIC9pe5s2f4HAsmmXDOkzymhVYCD1mzRxbvJUH1+u5Xa17o2ZMEHbehervDo1ajjL9bYycuwYGa6dlydx10ZMfbroy8XWbVulVcf21u72tuWpvECkX9VBALOVe3u1dA/Q9glryidqpcGgAMgVnUFhhsaBTZo6Vc7rNnTQG7ZssSwvxZ99NhBVYBkkECECiDncuXu3DBoxQjro/TN34UIporHWHdUogalwrt24YZWbWOcgdZVEmnbdsd11m/mNAV0t1bBx4tQpmRikUBJzLC5JwFcCfo969vVA4c3XTl1TsAzaBQHDYUkWdWvNnPSz1dGbvGevXzersm//AUFMl5GLly+bVWsJJQefRUuWyELtqDDwAYHG/sh6jcM8ceKkswgzcvO2xp907dtXenXsKI1r1ZR7muMTdedOmTHdaVU55XDNwyUOsbsu4OqAXHGcQ0K1PkIqaTD1mGHfSeI4/x9Z5joYAUHYkCEjR8qIsWPlrmPkrzc+73/6qUweN062qAIKGTnpJ+lgs4BaiW6+fKmPm93CTDp3/lyIa3ng0OEw9zEZoKzD5Qt58bXXTLJU1fXhvXvLW6q4QPHdqpa38xd7Sqfu3Z15ls6cbq3/ohwu2lxMnupjLGTeruW5cyEt0hj1Gwhx10ZMfSYOg7L7UOHFsRLZrNWBOLZrGWi7hQsVUqV8rRXkj/sA4R744HxLalD/ohUrrN12aozpbQ1NsMteDQXIlyePPYnrJBBpBGDNvqQvMaY/gNVw9fr1arA4LF3btpX82jZN+ETa1KlDzZjwpHpfsL8nSamWxFYaioRn81gd/Hlf4xQpJBAVCERJRRE3FJREuEZh9cIo0z3aufgivXVwQvLkySyLGkaQ/T5rtuTK/TBWDvtPmT7N+riWhZGtXdq1k16quCGW5PSZM1aWLOr+Mg8GJGB07H3t4MIjPVTx8CRQ1PDJmSOHDOnXT0YP6C9TZ86Qu44gZuPSSK5vmpCbN295KsqZPlnfduHO/lTd0hDEoXkSM6LUbPfEB9uXr14lGXLnstzNTd55R7qpVfLHKZPNrh6X4amPx0LcbIBC/36zT91sCTtp4ew5kl2vOQYv2ZW9xjpNxXl1yS5xuKJnqcWgcf0GIRTFcjo/WvOPPpbaVV6XdDrQ4qz+cwnEU338uZZhn0n4c5j61FBrqP2lKfwlhW8P/HNTTWWHeRMPu7x8HdJQD7iaIRgFWlqtuV31vjEvVUhHTJhRfPGbQgKRSSCPPqNTa980XD1OdjmtL/EYdIKBLni5wQtNieeek4Papo3gRQgjnsfoDAvuJK2W20r7O7w0TVADBZVEd5SY9qgIRIrrGVaqV8uWlZfKltNOoIRAETRyQG8qSPWqVa1tCLJHjAYElg/cfM0+/tj67ctXWnWjYv47zIaPjqfMc0V82U0u65vee7VqyTB122K/bxwjXTfoZKpG4Fq8qjd/V7UA2gVK3nP6tpktazYrGet4uwxLCuh0ChjAUvHll+W4Wq92qRUFgqlBjAuja8dOgnz9Hcrmug1/hFWstT2xsoNSG6hBCihr96bN1iAYuAY3bXk4qs9XK5Qv9Xm/4btWeAHaiD0W01v78QQDU8vgOqRMmUpSqCUL62Zam+/VbVyiUEErti9ZsuRWu8uRPbtVFOYhTJs0ibxcvrwVv1hDFUm8rNgFrtJmbdtYST+rhTUs8fdamvJd+aTQ+wThGCYkI1+evNY6lFdvYurTtnlLgYvsbVXeDuiIfRNf5W1ff7ZdV8v+Bh0N+o7+o0V+bdPx1KqL+zv3U0/Jy/p82O5o/xvVzQw3HtKMwBKJ+3KVTmxMIYFHQWCFtr1c2larqdcBFkMI7sHq+hsd6T6Nu4UsVI8VXnZKarw8Js/Gs+99fbGGV8hYHGugv9MBkBBMm4N5GDFQZpK6m+EHwn2BD/ankMCjJhApFsVm7drKht9+k7mTJlrn21ctaLDcQUZPmCCN6ulkoxpvB9mrlobiGqu0QN2C4zUODp9x4YjV+FzjRhar1fC8Y6Le9ToXXg69ucMSjDDFoJERGmj/usZFQvAb6UaSJ3to1TMPCZP++6xfJH2Kh8ot0lZqTCIEU5Z4E0x/smPXnzLLpmxg8IlxA7+uU7UsmDxZNqhVC4KBC74EN2NwAwbJ1FCldof+I0AgBFbUH3/+ybIiYhALZPG69dY0EHnU0uNNfKmPYb/Ica1fqFZN2TyMDfTWfjwdd5VjqhWzHddk4erVUlODxF+tUNFKBiMjW/bslfKvvya9NWaz0suvyBxtl5BDp89Ij69DW4QRNtBUwwRgAYZSuWzFCiu/p6+IXktTnjs+mIZjrE7Ia6RVk/cEn2/HjpNuvXqaZLdLU58zGm8F6TFwsPPlxO0OAUqcMmOGNeCsyiuvSGYdqQ+L4QO1NK7W8Ix5+oyAIC5xpN4TdXVkaWXNd0/DIhCnOF5jdTHylEICj4IALIf9hw2TsvrPQh01NAptFy80GLU8/IcfnM9mKIyjf/xR6urUX3X0A4UPMygM0VhiYyGvoLHo2/X5hn91qanPOniO8N/R+NiF/0Rkp8H1R0XA77/wy6/K0EF1094PwhnAqnRfOwmjOIXnELCOGMtJePZD3tT6tmh3R9r3hwXG3Yg2e57wrmP6GIwePuVwd7vuj4eILwqifT9YABE8fSOM4Gn7Pr6uY5Qu3o7htvZVglkfX+sQnnwYuIMH/C2d9y+QEpFrGcjju5aFuEFvcVPIH1s/uXRg0l9eQhhcy/Xld13HgJ2pGiZhOlDX/dARI570mi3O2DUPf5NAZBNIos9Wa+om9TzBUu5JMDgFcyj+64gB95SP6SQQlQn4bVG8o3GACXSQyS1dBlpgtYmoRFRJxPE8KYnYFmglEWVCEfakJGJ7eJVE7AMLYDCURJR9UkfkhVeCWZ/w1sWX/HZLsi/5fc0TkWvpa9kRyReWkogycX/jPg+0HNFwC7xseFIScTxMckwhgahG4K7+9/lmnf/1nzBeJPmCE9WuHOsTEQJ+WxTTpkolCfRfE055Gc0VkYpxHxIggahBIKNaHW9rx3j+0qWoUSHWggRIgARIINIIwKvkl6DziKcuulRqiqeQAAk8XgRwX+P+ppL4eF1Xng0JkAAJ+ErAb9czDnRCpwfJrCMt4aK6onNL3VY3VTBiFn09KeYjARKIOAG8PeJeTuFQEnF/U0iABEiABGImAb9dz3ZscEMn1eBzTO6MIf4UEiCB6EcAs4QiJvG6xgfSkhj9rh9rTAIkQAKBJBBQRTGQFWNZJEACJEACJEACJEACj5aA3zGKj7b6PDoJkAAJkAAJkAAJkECwCFBRDBZZlksCJEACJEACJEAC0ZwAFcVofgFZfRIgARIgARIgARIIFgEqisEiy3JJgARIgARIgARIIJoToKIYzS8gq08CJEACJEACJEACwSJARTFYZFkuCZAACZAACZAACURzAlQUo/kFZPVJgARIgARIgARIIFgE/P5nlmQ6wTaFBEiABEiABEiABGICgWv6ZwQxSfxWFGMasJjUOHiuJEACJEACJEACMZsAXc8x+/rz7EmABEiABEiABEjAIwEqih7RcAMJkAAJkAAJkAAJxGwCVBRj9vXn2ZMACZAACZAACZCARwJUFD2i4QYSIAESIAESIAESiNkEqCjG7OvPsycBEiABEiABEiABjwSoKHpEww0kQAIkQAIkQAIkELMJUFGM2defZ08CJEACJEACJEACHglQUfSIhhtIgARIgARIgARIIGYT8HvCbTu+tKlSSVL9p5b48eJJLPsGrpMACUQbAg+0pnf+/Veu678PnL90KdrUmxUlARIgARIIPIFYCdOlQ7/glzyhimHmJ5+Uf+/dkys3b8pt7WTu+1UidyYBEnhUBOBmSKD3dIrEiSVenDhy4tw5uav3dKAlc8aM8sQTT8jhI0cCXTTLI4GgEyhVrJhs2bEjKPdG0CvPA5BAOAgExPUMJfH67dty6soVuUUlMRz4mZUEoh4BvOThPsb9jPsa93cwpGiRIvLC888Ho2iWSQJBJRBXX6Aa1qkjSZMkCepxWDgJRAUCflsU4W5OoFYBdCoUEiCBx49AxhQp5PbduwFxQ8fRDrZcqVICJTFT+vQSK3ZsOXr8uKzdsEE2bdsmDx48dHD0/eILt50wLDg//PTT4weZZxQtCGTJlMlqv0WeftpZ3z82b5aV69bJhYsXnWmxYsWSb7p3l7m//261becGrpBANCTgd4wiYhLPX7sWDU+dVY7pBJKpNeCWWsz++++/UCjix48vCfRzNRq07fTp0slXXbtLv28HyYFDh0Kdi78JCCdJmyyZnPe3IN2/aqVKUr5MGRk5frwcUpdzHFUU8+bOLY1q15ZkSZPKkpUrraMk1OfKqAkTZPfevSGOahTJEIn8QQKRQCCpts/WH30k2/78U3oPGiRXrl6VdGnTSsUXX5Q2n3wiPQcOtGLzE2vbLfLMM25fdCKhmjwECQScgN+uZwxcQUyiO7muHYH5zJg0KUSWzatWObchT1QQU1f70td6fa0WELOfr/tEp3xR8Xp54wclcOmv861rsm3N2hBZn8qWTS5rmzupD/zLBw/KtIkTJbZaACCIt135+0K5sG+fnNi5U84cPCRQxCDly5S1yoNVITLkWe1sTJvCsmG9em4P+3TBglK3WhUpUbSo2+3+JuL+xn0eCHlG67pGrYf7VaG9pzHNiH3ctWeP/LZ0qZQpWdI6BK4BXHs3VEFFHvvn/n1GPwfiOrCM8BPIlT27FVM7a948S0lECWfPn5fJs2ZJPG2zhfLmlberVJHP27SRKq+84rSOh/9I3IMEohYBvxVFdK+eHt1lqlST8m+95faMazdqZG1bvnGj2+2PIrFw+fJS8tVXpcLbb1uHX6duLl9k7rRp0uK992Tddt/y+1JmVMsTFa+XN0ZQAgvmLyAXb/4TKtuCmbMEDs4X33hDWnf7QiqXKyc1dB3SqH59eS5fXqnesJEUq1hREseNI3179rS2RfbXHlVWcf94uodMfRYvWyZJtRP7WdthMAT390M12v/Sb966JVmzZAlV0MatW2XG3LlWeqJEiazlPzrqGi68DBojGV/DWygk8CgJ3NL2iNCJLDoIyy54eRmlFvKjJ07ITzNmyGddu1qfywzHsmPiejQm4Lei6O3cd+7eJVs07ui6G4sjRjpi28nTp90WkUfdUZvUDQVLyvG9+6RuzZpWviRqKUIaOnss4XLDsl7NWs5yvujSxUpD+qzJUwT7+CKo05mzZ7XsmbJMrR6V33zTl91k+46d8pSOgFu6YrlP+e2ZmqsrA/XE5/SBg1K5YiXn5tw5c8qxv/Y6t9u3IX//Xl87t33w7rvO/Z6IG9c6b1MurJ1GXlfXH9I/b9feWu7ftl1KOyw5Jo+7ZUSvF8oa/M03snbJUpk/Y6Z1zIVz5jitdNg+Zth3VvoBVbRn/jxZFjkUBmyrqdfAnMfff+6WrJkzIzlMmTB9hmTOm1tOnDweKu+CRYvkbX1R2Yp4t0k/WtsLF3rGWsZ1WM5Wrlkt+w4ckAs3bkrcuO6taYZliaLFQx3DNcHbtUQ7nzhmjBzZ/Zd1riOHDLF2v3PnjnWP4D7xJIYNlm9Vqx4iG9I8tRHU54QqomZ/e9sKUUiAf/yuSu1TWbNKp1atrFiv1ClTWkeA9dC4mRMmSGClwfrYr0cP6di62Y9mIgAAIdxJREFUtQxUZb2Ktl0KCTwqAgcOH5Z9agn/SI0C9dWYkDdXLsvyjfogjOL8hQuPqmo8LgkElUBQFUV/aj7lh/GSInkKeaNxY+3Qt8uYAQOstzlT4dH6Bnfzv3tqncgkc5cukw7amUDgfmvXtKl06t1HGrdsKRVLl5JmH37oc1XaaznxNffhv/+WzD66GLv37iUXIvCQQBxcn86dZdIvv1hWzGXqjv+qW1dnXTeqOy5JwgTyqebZffiITBszWhI4OlFkalCnljT57DPZsf+gDP7yS6f7tHOHDtZ519e4mS8HD7asnQULFLDKNdaaUs+XlDrK6cmUKWTM8O+cx4zoiqfrhfJS6YCnZ3LllA2bN0nT9h2kdOHC0rpZM+tQ5TReDW7T/qNGybffjZBKZUpLBoerN5UOohj/7bcyfcFvUklj2CBwC/siLdq3cxt7iH3bduksy5U1BG5byNLlD5X8KQ6r3NY16wSW4jRJEkvfQYOtPPYvXLupo0cLrM4bt2yyb3K77u1aZlILxVtqvezdv6+M+mmyvKPWzcK2YHm3BToSO/TqLZ379LF+JU780BJnz++pjaA+16/fkIq1asv85StDtS17GYFc36Mxh920vnvV5V+9cmX5Sl/qWmo7LJQ/v2U9xLFMG8VLQb+hQ6WNWmgmTZ8uVZRRUW07FBJ4FARgORz6/fcyYcoU60UX7bZPt25STb1QyTWGl0ICjysBo3dFufMrV/lVyV+sqKxZs0baa0cBKVWihLOeu/bsloOH/5b1mzZpvNNByaAjKCHbteNOmy+fjBo3VuYtWCAb1QrVuME7zv16fP65ZaWDpQ6fsqVLO7dhZboqbQPVuvNB3bo+KyUhCnDzAxY0czws46rFDwK3GuSeKrxHjh6VBu83kWLqBoWgs0Suz7S+k/TBVKdxIyu9tG06kUHDh1v1bdqqhbWtRLGHlq1vNKg6tVpkf1u8WIZ+91AJdI1v+1QVYljWeqoCnjVtGoEVEhIWHyuTm6+wrhd26amWxSnTp8nm3XvkHZ1aAlLPoQBi23djvpfDZ85a6fh6ycGidYf2skVdk7369rMUNxNP+NorFUNwNS8LzgLCWIHSvW7+fDmqcUYr1q62cmPwSnNlnjNTBnlJ29u0+QsElnG7ZEifUUarAgOp36SJc5On+vhyLberdW/MhAna1rtY5dWpUcNZrreVkWPHyHDtvDyJuzZi6tNFXy62btsqrTq2t3a3ty1P5QUi/aoOApit3NurpXuAtk+MFv1ErTQYFAC5oi67GRoHNmnqVDmv29BBb9iyRY6pa6/4s88GogosgwQiRACDqXbu3i2DRoyQDnr/zF240Bq40lGNEol0EAuFBB5HAg+1gyh4Zu3UNQXLoF0QMByWZFG31sxJP1sdvcl79vp1syr79h8QxHQZuXj5slm1lnBH4rNoyRJZqB0VBj78rUqcP7Je4zBPnDjpLMKM3LytI2679u0rvTp2lMa1aso9zfGJuoSnzJjutKqccrjm4RKHwMpmxLg6rjjOIaFaHyGVKlSw3LmJ4/x/ZJnrYAQEYUOGjBwpI8aOlbuOkb9h8bF2cvMV1vXCuRmp+EZ1p/UT53Pz3gOzSd03562RhEhIkfyhWxLxhnbBQAfU99z5cyGu5YFDh+3ZvK5DWYfLF/Lia68581bV9eG9e8tbqrgcPXZMtqrl7fzFntJJp7owsnTmdGv1F1XEL9qmxPBUH2Mh83Ytz50L6bbCqN9AiLs2YuozcRiU3YcKL46VyGatDsSxXcvAtS5cqJAq5WutQH/cBwhpwAfnW7J4cVm0YoW120695rfV9W6XvRoKkC9PHnsS10kg0gjAmn1JX2JMf3BTwyVWr1+vBovD0rVtW8mvbRPTN1FI4HEjECUVxSfTpLGURLhGYfXCKNM92rn4Ir11cELy5MksixpGVP4+a7bkyp3TuSssWvi4Cka2dmnXTq1WfeWcupFPnzljZcmi7i/zYEACrFn3HXO9uZbh6XcPVTw8CRQ1fHLmyCFD+vWT0QP6y9SZM+SuKpEQ49JIrlMzQG7evGUtvX1N1rdduLM/Vbc0BHFonsSMKDXbPfEx290tw3u97NPR7Ni5S15XSxKCxFGXkqpIHHEoxbduPxyIklJjgez7mDpAoX+/2afmZ7iWC2fPkex6zTF4ya7sNW7QQM6rS3aJwxU9Sy0Gjes3CKEolqteXZp/9LHUrvK6pNOBFmf1n0sgnurjz7UM10n5mNnUp4ZaQ+0vTT7uHuFs+OemmsoO8yYednn5OqShHib+9HlVGEurNber3jfmpQoHRUyYUXwjXAnuSAIRJJBHn9GptW8arh4nu5zW59U/+rzGM4xCAo8jgUhxPcNK9WrZsvJS2XLyfPESAsXCyAG1EkCqV61qbUOQffLkya00WD5w8zX7+GPrty9fadWNivnvYut+6HjKPFfEl90EI9Teq1VLhqnbFvt94xjpukEnUzUC1+JV7dC6qgXQLlDyntO3zWxZs1nJWMfbZVhSQKdTwACWii+/LMfVerXLYTmDxezajRvW7l07dhLk6+9QNtdt+COsYq3tiZUdlNpAD1II9PWa9L8pVn2vaJA43PJ2WbV2jfWz1SfNLNf4N199ZQ3SsefxtI6pZXAdUqZMJSnUkoV1M63N9+o2LlGooBXblyxZcqvd5cie3SoK8xCmTZpEXi5f3opfrKGKJF5W7AJXabO2baykn8eNs29yu+7vtTSFvt/wXSv8AvcQ3OYp9D5BOIYJyciXJ6+1DuXVm5j6tG3eUhLr3/S9rcobBhJhSqFgynW17G/QEAKEHeTXNh1Prbq4v3M/9ZS8rM+H7Y72v1HdzHDjIc0ILJG4L1fpxMYUEngUBFZo28ulbbWaeh3Spk5tVQH3YHX9jY50n8bdUkjgcSQQKRbFZu3ayobffpO5kyZaDPuqBQ2WO8joCROkUb0G8rPG20H2qqWhuFqYFqhbEAMZ8BkXjmk/Pte4kcVqMTzvmKh3vc6Fl0Nv7rAEI0wxaGSEBtq/rnGREPxGupHkyR5a9cxDwqT/PusXSZ/ioXKLtJUakwjBlCXeBNOf7Nj1p8yyKRsYfGLcwK/rVC0LJk+WDWrVgmDggi8TQGNwAwbJ1FCldsf+/d6qEO5tgb5ex0+elKI6SKH1p5/qYJfNOkCnjnMwy8lTp+Qrvf492n5mfVDZKmrx80VW2UZOIz+uycLVq6Vmw4byaoWKVhFgZGTLnr1S/vXXpLfGbFZ6+RWZo+0Scuj0GenxdWiLMMIGmmqYACzAUCqXOVym1k5uviJ6LU1Rpm0uctwLL1SrJvk0DnWsTvxrpFWT9wSfb8eOk269eppkt0tTnzMabwXpMXCw8+XE7Q4BSpyi04dgwBnmmcusI/VhMXyglsbVGp4xT58REMQljtR7oq6OLK2s+e5pmAHiFMdrrC5GnlJI4FEQgOWw/7BhUlb/Waijhkah7eKFBrGzw3/4wadn86OoN49JAv4S8Psv/PKrMnRQ3bT3/a2Jm/1hNbmvnYRRnNxk8ZgE64ixnHjM5GFDan1btLsj7dlggUFsSiAFA0nSqJX1lMPd7Vo23M++KIj2/WBNTKR1veGwTNq3BWvdn+uFOoHtUVVc5qsF712X+FS8ueOfECJLMKoZ1q5bOu9fICUi1zKQx3ctC3GDiLvyJrF1Yy4dLPaXlxAGb/t72lbXMWBnqoZJ2F3M9vzoiBFPes0WZ2zfznUSeBQEkuizypq6ST1PsJRTSOBxJuC3RfGOxgEm0EEmt3QZaIHVJqISUSURx/OkJGJboJVElAlF2JOSiO3hVRKxD+IoI1NJxDEjer0wKhxT5hjp3b+/WXUuI1NJxEHtlmRnJQKwEpFrGYDDeiwiLCURO+L+xn0eaDmi4RaIS/WkJOJ4mOSYQgJRjcBd/e/zzTq/6T8BfpGMaufJ+pAACPhtUUyrc+Ql0H9NOBWGVYK4ScATAcSepdZ2BKUFI40pUYtARrU63taO8fylS1GrYqwNCZAACZBA0An4rSiihjl0VPJ1tf5dCrBLNuhnzwOQAAl4JZBKXWxJNQTksMaSUkiABEiABGIeAb9dz0B2QqcHyawjLeGiuqLK4m11UwUjZjHmXR6eMQlEPgHEJOJeTqFKYjyN08T9TSEBEiABEoiZBAJiUTTo4IZOqsHnmNw5lknkkgRIIFoRwPTniEm8rvGBdDdHq0vHypIACZBAwAkEVFEMeO1YIAmQAAmQAAmQAAmQwCMjAC8ThQRIgARIgARIgARIgARCEaCiGAoJE0iABEiABEiABEiABECAiiLbAQmQAAmQAAmQAAmQgFsCVBTdYmEiCZAACZAACZAACZAAFUW2ARIgARIgARIgARIgAbcEqCi6xcJEEiABEiABEiABEiABKopsAyRAAiRAAiRAAiRAAm4J+P3PLMl0gm0KCZAACZAACZAACcQEAtf0zwhikvitKMY0YDGpcfBcSYAESIAESIAEYjYBup5j9vXn2ZMACZAACZAACZCARwJUFD2i4QYSIAESIAESIAESiNkEqCjG7OvPsycBEiABEiABEiABjwSoKHpEww0kQAIkQAIkQAIkELMJUFGM2defZ08CJEACJEACJEACHglQUfSIhhtIgARIgARIgARIIGYToKIYs68/z54ESIAESIAESIAEPBKgougRDTeQAAmQAAmQAAmQQMwm4PeE23Z8aVOlkqT6Ty3x48WTWPYNXCcBEohSBB5obe78+69c138YOH/pUpSqGytDAiRAAiQQdQjESpguHfoMv+QJVQwzP/mk/Hvvnly5eVNuawd0368SuTMJkEAwCcCVkEDv2xSJE0u8OHHkxLlzclfv28iUzBkzyhNPPCGHjxyJzMPyWCQQEAKlihWTLTt2RPp9E5DKsxASCAeBgLieoSRev31bTl25IreoJIYDP7OSwKMhgBc53Ku4Z3Hv4h6ObClapIi88PzzkX1YHo8E/CYQV1+uGtapI0mTJPG7LBZAAlGdgN8WRbibE6hVAB0OhQRIIHoSyJgihdy+ezfobug42sGWK1VKoCRmSp9eYsWOLUePH5e1GzbIpm3b5MGDhw6Ovl984bYThgXnh59+ip6QWetoTyBLpkxW+y3y9NPOc/lj82ZZuW6dXLh40Up7/513pGjhws7tZuX6jRvS8csvzU8uSSDaEPA7RhExieevXYs2J8yKxiwCqVQBuuThJSZF8uRy69ataOE6ekGVqwZ160qrtm3l7n//BfwiImQkbbJkcj7gJYcssGqlSlK+TBkZOX68HFKXcxxVFPPmzi2NateWZEmTypKVK60dEupzZdSECbJ7794QBRhFMkQif5BAJBBIqu2z9UcfybY//5TegwbJlatXJV3atFLxxRelzSefSM+BA+W2xvyi7S5dtUpmL1gQCbXiIUgg+AT8dj1j4ApiEt3Jde0IzGfGpEkhsmzWG8lswzIqiL0+Zt3Xen2tFpDw7uNr2VElH87v3QYNokp1JJm6fZb+Ot/ivm3N2hD1qvraa1b60e3breUnH3zo3J4ta1a5oudyXK1TFw8c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"
    }
   },
   "cell_type": "markdown",
   "id": "cbb5d1f3",
   "metadata": {},
   "source": [
    "# Perplexity\n",
    "\n",
    "링크: https://www.perplexity.ai/\n",
    "\n",
    "- **설립연도**: 2022년\n",
    "- **주요 투자자**: Jeff Bezos, Nvidia, Databricks, Bessemer Venture Partners, IVP, Wayra 등\n",
    "- **최근 펀딩**: 5억 달러 (2024년 10월)\n",
    "- **기업 가치**: 약 90억 달러 (2024년 11월 기준)\n",
    "- **월간 활성 사용자**: 1,500만 명\n",
    "\n",
    "## Perplexity Pro 정확한 특징\n",
    "\n",
    "- **일일 Pro 검색**: 300회\n",
    "- **AI 모델 선택**: GPT-4 Omni, Claude 3 Sonnet/Haiku, Sonar Large 32k[5]\n",
    "- **파일 분석**: PDF, CSV, 이미지 파일 지원\n",
    "- **가격**: 월 $20 또는 연 $200\n",
    "\n",
    "## Perplexity API 사용 방법\n",
    "\n",
    "**가격**\n",
    "\n",
    "![perplexity-pricing.png](attachment:perplexity-pricing.png)\n",
    "\n",
    "- **API 크레딧 획득**\n",
    "   - Perplexity Pro 구독 시 **매월 $5 상당의 API 크레딧 제공**\n",
    "\n",
    "- **API 모델 옵션**\n",
    "   - Llama 3 기반 모델\n",
    "   - Perplexity 온라인 LLM\n",
    "   - 인용 기능 포함\n",
    "\n",
    "- API 키 발급: [API 콘솔](https://www.perplexity.ai/settings/api)\n",
    "\n",
    "API 키 발급 후 `.env` 파일에 키 저장\n",
    "\n",
    "```\n",
    "PPLX_API_KEY=이곳에 API 키를 입력하세요.\n",
    "```\n",
    "\n",
    "혹은\n",
    "\n",
    "```\n",
    "import os\n",
    "\n",
    "os.environ[\"PPLX_API_KEY\"] = \"이곳에 API 키를 입력하세요.\"\n",
    "```\n",
    "\n",
    "**참고**\n",
    "\n",
    "- [API 문서](https://docs.perplexity.ai/api-reference/chat-completions)\n",
    "\n",
    "## 지원 모델\n",
    "\n",
    "| Model                                 | Parameter Count | Context Length | Model Type        |\n",
    "|---------------------------------------|-----------------|----------------|-------------------|\n",
    "| `llama-3.1-sonar-small-128k-online`   | 8B              | 127,072        | Chat Completion   |\n",
    "| `llama-3.1-sonar-large-128k-online`   | 70B             | 127,072        | Chat Completion   |\n",
    "| `llama-3.1-sonar-huge-128k-online`    | 405B            | 127,072        | Chat Completion   |\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2afed6bb",
   "metadata": {},
   "source": [
    "## ChatPerplexity 매개변수\n",
    "\n",
    "`model`  \n",
    "사용할 언어 모델을 지정 (예: \"llama-3.1-sonar-small-128k-online\") - 기본 성능과 능력을 결정.\n",
    "\n",
    "`temperature`  \n",
    "응답의 무작위성을 조절 (0.0-1.0), 0은 결정적, 1은 가장 무작위한 응답 생성.\n",
    "\n",
    "`top_p`  \n",
    "토큰 샘플링의 확률 임계값 설정 (0.0-1.0), 높을수록 더 다양한 출력 허용.\n",
    "\n",
    "`search_domain_filter`  \n",
    "검색 결과를 지정된 도메인으로 제한, 리스트 형태로 제공 (예: [\"perplexity.ai\"]).\n",
    "\n",
    "`return_images`  \n",
    "응답에 이미지 포함 여부를 결정하는 불리언 플래그.\n",
    "\n",
    "`return_related_questions`  \n",
    "관련 질문 제안 기능을 활성화/비활성화하는 불리언 플래그.\n",
    "\n",
    "`top_k`  \n",
    "사용할 검색 결과의 수 제한 (0은 제한 없음을 의미).\n",
    "\n",
    "`streaming`  \n",
    "응답을 스트리밍으로 받을지 완성된 형태로 받을지 결정하는 불리언 플래그.\n",
    "\n",
    "`presence_penalty`  \n",
    "토큰 반복에 대한 페널티 (-2.0에서 2.0), 높을수록 재사용을 억제.\n",
    "\n",
    "`frequency_penalty`  \n",
    "일반적/희귀 토큰 선호도 조정 (-2.0에서 2.0), 높을수록 희귀 토큰 선호."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "620cfb66",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_teddynote.models import ChatPerplexity\n",
    "\n",
    "perplexity = ChatPerplexity(\n",
    "    model=\"llama-3.1-sonar-large-128k-online\",\n",
    "    temperature=0.2,\n",
    "    top_p=0.9,\n",
    "    search_domain_filter=[\"perplexity.ai\"],\n",
    "    return_images=False,\n",
    "    return_related_questions=True,\n",
    "    # search_recency_filter=\"month\",\n",
    "    top_k=0,\n",
    "    streaming=False,\n",
    "    presence_penalty=0,\n",
    "    frequency_penalty=1,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b259e803",
   "metadata": {},
   "source": [
    "응답을 출력합니다. `ChatPerplexity` 는 지식 정보의 출처를 `citations` 속성에 저장합니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4767c520",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 응답 출력\n",
    "response = perplexity.invoke(\"2024년 노벨문학상 수상자를 조사해 주세요\")\n",
    "print(response.content)\n",
    "\n",
    "print()\n",
    "for i, citation in enumerate(response.citations):\n",
    "    print(f\"[{i+1}] {citation}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5e26c7b",
   "metadata": {},
   "source": [
    "스트리밍 출력"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b4607a67",
   "metadata": {},
   "outputs": [],
   "source": [
    "response = perplexity.stream(\"2024년 노벨문학상 수상자를 조사해 주세요\")\n",
    "\n",
    "for token in response:\n",
    "    print(token.content, end=\"\", flush=True)\n",
    "\n",
    "print(\"\\n\")\n",
    "for i, citation in enumerate(token.citations):\n",
    "    print(f\"[{i+1}] {citation}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7cbf362a",
   "metadata": {},
   "source": [
    "## Together AI\n",
    "\n",
    "- 링크: https://www.together.ai/\n",
    "- API 키 발급: https://api.together.ai/\n",
    "- `TOGETHER_API_KEY` 환경변수 설정\n",
    "  \n",
    "Together AI는 2022년 샌프란시스코에서 설립된 생성형 AI 클라우드 플랫폼 회사입니다(NVIDIA, Kleiner Perkins, Lux, NEA 등으로부터 1억 2천만 달러 이상의 투자를 유치했습니다).\n",
    "\n",
    "### 주요 제품과 특징\n",
    "\n",
    "**Together Inference**\n",
    "\n",
    "- 업계에서 가장 빠른 추론 스택을 제공하며, vLLM보다 최대 4배 빠른 성능을 보입니다\n",
    "- Llama-3 70B 사용 시 GPT-4 대비 11배 낮은 비용으로 운영 가능\n",
    "- 자동 확장 기능으로 API 요청 볼륨에 맞춰 용량이 자동으로 조정됩니다\n",
    "\n",
    "**Together Custom Models**\n",
    "\n",
    "- 사용자 맞춤형 AI 모델 학습 및 Fine-tuning 지원\n",
    "- FlashAttention-3와 같은 최신 최적화 기술 적용\n",
    "- 학습된 모델에 대한 완전한 소유권 보장\n",
    "\n",
    "### 기술적 특징\n",
    "\n",
    "**성능 최적화**\n",
    "\n",
    "- FlashAttention-3 커널과 독점 커널을 통합한 추론 엔진 보유\n",
    "- Medusa와 SpecExec 같은 추측적 디코딩 알고리즘 적용\n",
    "- 최고의 정확도와 성능을 위한 독자적인 양자화 기술 사용\n",
    "\n",
    "**지원 모델**\n",
    "\n",
    "- Google Gemma, Meta의 Llama 3.3, Qwen2.5, Mistral AI의 Mistral/Mixtral 등 200개 이상의 오픈소스 모델 지원\n",
    "- 멀티모달 AI 모델 지원으로 다양한 형태의 데이터 처리 가능\n",
    "\n",
    "**보안 및 프라이버시**\n",
    "\n",
    "- 사용자가 명시적으로 동의하지 않는 한 데이터는 새로운 모델 학습에 사용되지 않음\n",
    "- 데이터 보관에 대한 완전한 제어권을 사용자에게 제공"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a6b794c1",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_teddynote.messages import stream_response\n",
    "from langchain_together import ChatTogether\n",
    "\n",
    "together = ChatTogether(model=\"meta-llama/Llama-3.3-70B-Instruct-Turbo\", temperature=0)\n",
    "# together = ChatTogether(model=\"google/gemma-2-27b-it\", temperature=0)\n",
    "\n",
    "answer = together.stream(\"로또 생성기 파이썬 코드를 작성하세요\")\n",
    "stream_response(answer)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61f0b7d9",
   "metadata": {},
   "source": [
    "function calling 지원"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5bfc6d49",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pydantic import BaseModel\n",
    "from typing import List\n",
    "\n",
    "\n",
    "class Lotto(BaseModel):\n",
    "    numbers: List[int]\n",
    "\n",
    "\n",
    "together_structured = together.with_structured_output(Lotto)\n",
    "\n",
    "answer = together_structured.invoke(\"로또 번호 6개를 추천해 주세요\")\n",
    "print(answer)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56ea6a72",
   "metadata": {},
   "source": [
    "# Cohere\n",
    "\n",
    "Cohere는 기업용 인공지능 솔루션을 제공하는 선도적인 AI 기업으로, 대규모 언어 모델(LLM)을 개발하여 기업들이 AI 기술을 쉽게 도입하고 활용할 수 있도록 돕고 있습니다.\n",
    "\n",
    "## Cohere 개요\n",
    "\n",
    "- **설립연도**: 2020년\n",
    "- **주요 투자자**: Inovia Capital, NVIDIA, Oracle, Salesforce Ventures\n",
    "- **시리즈 C 펀딩**: 2억 7000만 달러 유치\n",
    "- **기업 미션**: 기업용 AI 플랫폼 제공\n",
    "\n",
    "## 주요 제품\n",
    "\n",
    "### Command R+\n",
    "\n",
    "Command R+는 기업용으로 최적화된 Cohere의 최신 LLM입니다. \n",
    "\n",
    "#### 주요 특징\n",
    "\n",
    "- **긴 컨텍스트 윈도우**: 128k 토큰 지원\n",
    "- **고급 RAG 기능**: 검색 강화 생성 기능 제공\n",
    "- **다국어 지원**: 10개 주요 비즈니스 언어 지원\n",
    "- **자동화 도구 사용 기능**: 복잡한 비즈니스 프로세스 자동화\n",
    "\n",
    "### Aya\n",
    "\n",
    "Aya는 Cohere의 비영리 연구소인 Cohere for AI에서 개발한 오픈소스 다국어 LLM입니다. \n",
    "\n",
    "#### 주요 특징\n",
    "\n",
    "- **언어 지원**: 101개 언어 지원 (기존 오픈소스 모델의 두 배 이상)\n",
    "- **훈련 데이터셋**: 5억 1300만 개의 데이터 포인트 포함하는 대규모 다국어 훈련 데이터셋 공개\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f194b806",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_cohere import ChatCohere\n",
    "\n",
    "# ChatCohere 객체를 생성합니다.\n",
    "cohere = ChatCohere(temperature=0)\n",
    "\n",
    "# 스트리밍 출력을 위하여 invoke() 대신 stream()을 사용합니다.\n",
    "answer = cohere.stream(\"사랑이 뭔가요?\")\n",
    "\n",
    "# 답변 출력\n",
    "stream_response(answer)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f640b099",
   "metadata": {},
   "source": [
    "# Upstage\n",
    "\n",
    "Upstage는 인공지능(AI) 기술, 특히 대규모 언어 모델(LLM)과 문서 AI 분야에 특화된 국내 스타트업입니다.\n",
    "\n",
    "## 주요 제품 및 기술\n",
    "\n",
    "### Solar LLM\n",
    "- **주요 특징**: Upstage의 주력 대규모 언어 모델로, 빠른 성능과 비용 효율성으로 주목받고 있습니다.\n",
    "- **기술적 접근**: Depth-Up Scaling (DUS) 기술을 적용하여 성능을 극대화합니다.\n",
    "- **플랫폼 통합**: Amazon SageMaker JumpStart 등 다양한 플랫폼을 통해 API로 통합 제공됩니다.\n",
    "\n",
    "### Document AI Pack\n",
    "- **기능**: OCR 기술을 기반으로 한 문서 처리 솔루션으로, 복잡한 문서에서 필요한 내용을 정확히 추출하고 디지털화합니다.\n",
    "\n",
    "### AskUp Seargest\n",
    "- **특징**: 개인화된 검색 및 추천 서비스를 제공하며, 기존의 ChatGPT 통합 무료 챗봇 AskUp의 업그레이드 버전입니다.\n",
    "\n",
    "## API 키 발급\n",
    "API 키 발급은 [여기](https://console.upstage.ai/api-keys)에서 가능합니다.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "5350647b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# UPSTAGE API KEY 설정\n",
    "# import os\n",
    "\n",
    "# os.environ[\"UPSTAGE_API_KEY\"] = \"이곳에 API KEY를 입력하세요.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cc739c29",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_upstage import ChatUpstage\n",
    "\n",
    "# ChatUpstage 객체를 생성합니다.\n",
    "upstage = ChatUpstage(model=\"solar-pro\")\n",
    "\n",
    "# 스트리밍 출력을 위하여 invoke() 대신 stream()을 사용합니다.\n",
    "answer = upstage.stream(\"사랑이 뭔가요?\")\n",
    "\n",
    "# 답변 출력\n",
    "stream_response(answer)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41206a27",
   "metadata": {},
   "source": [
    "## Xionic\n",
    "\n",
    "사이오닉에이아이(Sionic AI)는 대한민국의 유망한 인공지능 스타트업으로, 기업용 생성형 AI 솔루션을 개발하고 있습니다. 다음은 이 회사에 대한 주요 정보입니다:\n",
    "\n",
    "### 주요 제품\n",
    "\n",
    "1. **STORM Platform**: 기업이 생성형 AI를 기술적 고민 없이 바로 적용할 수 있도록 하는 플랫폼\n",
    "2. **STORM Answer**: 기업에 최적화된 생성형 AI 솔루션으로 비즈니스 생산성 향상을 목표로 함\n",
    "3. **Xionic**: 상업적 이용이 가능한 라이센스의 한국어 AI 모델\n",
    "\n",
    "상업적 이용이 가능한 라이센스의 한국어 모델\n",
    "\n",
    "- 링크: https://github.com/sionic-ai/xionic"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2abab6a5",
   "metadata": {},
   "source": [
    "(참고) 2024.11.29 기준 사용불가 (API 서버 오류)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "10f39d3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_teddynote.messages import stream_response\n",
    "\n",
    "# 2024. 11. 21 업데이트 코드\n",
    "xionic = ChatOpenAI(\n",
    "    model_name=\"xionic-1-72b-20240919\",\n",
    "    base_url=\"https://sionic.chat/v1/\",\n",
    "    api_key=\"934c4bbc-c384-4bea-af82-1450d7f8128d\",\n",
    ")\n",
    "\n",
    "# 스트리밍 출력을 위하여 invoke() 대신 stream()을 사용합니다.\n",
    "answer = xionic.stream(\"사랑이 뭔가요?\")\n",
    "\n",
    "# 답변 출력\n",
    "stream_response(answer)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d7b3eb61",
   "metadata": {},
   "source": [
    "# LogicKor\n",
    "\n",
    "LogicKor는 한국어 언어 모델의 다분야 사고력을 평가하기 위해 만들어진 벤치마크 리더보드입니다.\n",
    "\n",
    "## 목적\n",
    "\n",
    "한국어 언어 모델의 다양한 분야에서의 사고력을 측정하는 벤치마크\n",
    "\n",
    "## 평가 영역\n",
    "\n",
    "- 한국어 추론\n",
    "- 수학\n",
    "- 글쓰기\n",
    "- 코딩\n",
    "- 이해력\n",
    "\n",
    "## 주요 특징\n",
    "\n",
    "1. **다양한 모델 평가**: 국내외 다양한 언어 모델들의 성능을 비교할 수 있음\n",
    "2. **객관적 성능 측정**: 모델의 실제 성능을 다각도로 평가하여 객관적인 지표 제공\n",
    "3. **오픈 소스**: 누구나 접근하고 결과를 확인할 수 있는 오픈 플랫폼\n",
    "\n",
    "LogicKor 리더보드는 한국어 AI 모델의 발전을 위한 중요한 도구로 자리잡고 있으며, 지속적인 개선과 발전이 기대되고 있습니다.\n",
    "\n",
    "- 링크: [LogicKor 리더보드](https://lk.instruct.kr/)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
